接下來幾天,我將提供自己設計的VBA程式,這些程式用來串接ODK Central API,可以達到使用Access VBA登入、登出ODK Central,下載問卷報告檔案,然後轉入Access資料庫中使用。
ODK Central 後端(Backend)是一個 RESTful API 伺服器,提供建立和管理 ODK 資料收集活動的關鍵功能。
它與Central前端(Frontend,一個獨立的前端介面)相結合,形成了 ODK Central,這是一個完整的用戶可安裝的 ODK 伺服器解決方案。
雖然Central前端是 ODK Central API 的主要使用者,但該伺服器提供的 API 是完全公開且通用的,可以在使用者介面中完成的任何操作,也都可以直接透過 API 完成。
相關說明文件網址:
https://docs.getodk.org/central-api-authentication/
只有使用電子郵件帳號的使用者,可以透過這種方式進行身份驗證。
它主要由兩個步驟組成:
登入:提供電子郵件地址和密碼進行驗證,然後建立新連線階段,與其相關的是不記名通行證(Token)和過期時間,連線階段在建立連線後 24 小時過期。
使用連現階段:對於API的每個請求(request)都需要附加一個標頭「Authorization: Bearer {token}」,這將驗證該特定請求,是否屬於透過登入所建立的連線階段。
為了讓使用者登入新連現階段,您必須提供 JSON 格式的憑證。出於安全原因,唯一可能的結果是成功或失敗,失敗時沒有提供詳細資訊。它僅適用於 GET 請求,並且僅適用於 HTTPS。
以下為VBA程式:
Function ODK_Login(str_user, str_password)
On Error GoTo errHandle
Dim strUrl As String
Dim strReqBody As String
Dim strResponse As String
strUrlOpt = "/v1/sessions"
strReqHeader1 = "Content-type"
strReqHeader2 = "application/json"
strMethod = "POST"
strReqBody = Config("ODK_Login_Body")
strReqBody = Replace(strReqBody, "{user}", str_user)
strReqBody = Replace(strReqBody, "{password}", str_password)
strUrl = ConfigCloud("F_ODK_Url") & strUrlOpt
Set hReq = CreateObject("MSXML2.ServerXMLHTTP")
With hReq
.Open strMethod, strUrl, False
.setRequestHeader strReqHeader1, strReqHeader2
.send strReqBody
While hReq.ReadyState <> 4
DoEvents
Wend
strResponse = hReq.responseText
End With
JsonParser.InitScriptEngine
Set root = JsonParser.DecodeJsonString(strResponse)
strToken = JsonParser.GetProperty(root, "token")
If Len(strToken) = 64 Then
strCreatedAt = UTC_0600(JsonParser.GetProperty(root, "createdAt"))
strExpiresAt = UTC_0600(JsonParser.GetProperty(root, "expiresAt"))
Call ConfigLocalSave("ODK_Token", strToken, strResponse)
Call ConfigLocalSave("ODK_Token_createdAt", strCreatedAt, "")
Call ConfigLocalSave("ODK_Token_expiresAt", strExpiresAt, "")
ODK_Login = True
Else
ODK_Login = False
End If
Exit Function
errHandle:
MsgBox Err.Number & ": " & Err.DESCRIPTION
End Function
以上程式中,有呼叫一些外部程式,以下進行說明:
讀取設定:Config()、ConfigLocal()、ConfigCloud()
儲存設定:ConfigSave()、ConfigLocalSave()、ConfigCloudSave()
Access VBA 的眉眉角角Day8: 於VBA中的設定值存取方法
https://ithelp.ithome.com.tw/m/articles/10185444
這裡有介紹Config()與ConfigSave()這對函數,而ConfigLocal()、ConfigCloud()則是此組函數的延伸,分別是儲存於temp資料夾內的access檔案的ConfigLocal(),以及使用SQL Server的ConfigCloud(),這可以讓不同場合,儲存不同的設定資訊。如果不是在公司環境使用,僅單機使用,其實用Config()即可。
ConfigCloud("F_ODK_Url")的內容為ODK Central的網址。
ODK_Login_Body內容:
使用此JSON內容進行登入作業
{
"email": "{user}",
"password": "{password}"
}
將UTC字串的日期時間資訊轉換成-6時區,由於該字串會長的像「2024-10-07T18:52:45.006Z」,這要整理過才能轉入Access中,且UTC時區為0,調整目前所在定時區才是的正確時間。這個可依照自己所在時區調整。
Public Function UTC_0600(strUTC) As String
If IsNull(strUTC) Then
UTC_0600 = ""
Exit Function
End If
If Len(strUTC) = 29 Then
iDiff = Mid(strUTC, 25, 2)
If IsNumeric(iDiff) Then iDiff = Int(iDiff)
Else
iDiff = 0
End If
UTC_0600 = left(strUTC, 10) & " " & Mid(strUTC, 12, 8)
UTC_0600 = DateAdd("h", -6 + iDiff, CDate(UTC_0600))
End Function
成功登入後,會將登入的通行證(Token)存放在Access的ODK_Token上,接下來呼叫API時,都需要呼叫這文字串資料進行驗證,登出也不例外。
以下是登出作業時,使用的VBA程式碼:
Function ODK_LogOut()
Dim strUrl As String
Dim strReqBody As String
strUrlOpt = "/v1/sessions/" & ConfigLocal("ODK_Token")
strReqBody = ""
strReqHeader1 = "Authorization"
strReqHeader2 = "Bearer " & ConfigLocal("ODK_Token")
strMethod = "DELETE"
strUrl = ConfigCloud("F_ODK_Url") & strUrlOpt
Set hReq = CreateObject("MSXML2.XMLHTTP")
With hReq
.Open strMethod, strUrl, False
.setRequestHeader strReqHeader1, strReqHeader2
.send strReqBody
While hReq.ReadyState <> 4
DoEvents
Wend
strResponse = hReq.responseText
Debug.Print strResponse
If InStr(strResponse, ":true") > 0 Then
ODK_LogOut = True
'把過期時間歸零,表示已登出
Call ConfigLocalSave("ODK_Token_expiresAt", "", "")
Else
ODK_LogOut = False
End If
End With
End Function